﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Skill.Ode;

namespace Skill.Ode.Extension
{
    /// <summary>
    /// Defines some extention methods for Ode and Xna
    /// </summary>
    public static class XnaExtension
    {
        #region Vector3
        /// <summary>
        /// Convert to Xna Vector3
        /// </summary>
        /// <param name="vector"></param>
        /// <returns>Xna Vector3</returns>
        public static Vector3 ToXna(this DVector3 vector)
        {
            return new Vector3(vector.X, vector.Y, vector.Z);
        }

        /// <summary>
        /// Copy to Xna Vector3
        /// </summary>
        /// <param name="vector"></param>        
        /// <param name="xnaVector">Xna Vector3 to fill</param>
        public static void ToXna(this DVector3 vector, ref Vector3 xnaVector)
        {
            xnaVector.X = vector.X;
            xnaVector.Y = vector.Y;
            xnaVector.Z = vector.Z;
        }

        /// <summary>
        /// Convert to Ode DVector3
        /// </summary>
        /// <param name="vector"></param>
        /// <returns>Ode DVector3</returns>
        public static DVector3 ToOde(this Vector3 vector)
        {
            return new DVector3(vector.X, vector.Y, vector.Z);
        }

        /// <summary>
        /// Copy to Ode DVector3
        /// </summary>
        /// <param name="vector"></param>        
        /// <param name="odeVector">Ode DVector3 to fill</param>
        public static void ToOde(this Vector3 vector, ref DVector3 odeVector)
        {
            odeVector.X = vector.X;
            odeVector.Y = vector.Y;
            odeVector.Z = vector.Z;
        }
        #endregion

        #region Vector4
        /// <summary>
        /// Convert to Xna Vector4
        /// </summary>
        /// <param name="vector"></param>
        /// <returns>Xna Vector4</returns>
        public static Vector4 ToXna(this DVector4 vector)
        {
            return new Vector4(vector.X, vector.Y, vector.Z, vector.W);
        }

        /// <summary>
        /// Copy to Xna Vector4
        /// </summary>
        /// <param name="vector"></param>        
        /// <param name="xnaVector">Xna Vector4 to fill</param>
        public static void ToXna(this DVector4 vector, ref Vector4 xnaVector)
        {
            xnaVector.X = vector.X;
            xnaVector.Y = vector.Y;
            xnaVector.Z = vector.Z;
            xnaVector.W = vector.W;
        }

        /// <summary>
        /// Convert to Ode DVector4
        /// </summary>
        /// <param name="vector"></param>
        /// <returns>Ode DVector4</returns>
        public static DVector4 ToOde(this Vector4 vector)
        {
            return new DVector4(vector.X, vector.Y, vector.Z, vector.W);
        }

        /// <summary>
        /// Copy to Ode DVector4
        /// </summary>
        /// <param name="vector"></param>        
        /// <param name="odeVector">Ode DVector4 to fill</param>
        public static void ToOde(this Vector4 vector, ref DVector4 odeVector)
        {
            odeVector.X = vector.X;
            odeVector.Y = vector.Y;
            odeVector.Z = vector.Z;
            odeVector.W = vector.W;
        }
        #endregion

        #region Matrix3
        /// <summary>
        /// Convert to Xna Matrix
        /// </summary>
        /// <param name="m"></param>
        /// <returns>Xna Matrix</returns>
        public static Matrix ToXna(this DMatrix3 m)
        {
            return new Matrix(m.M11, m.M12, m.M13, 0,
                m.M21, m.M22, m.M23, 0,
                m.M31, m.M32, m.M33, 0,
                m.M41, m.M42, m.M43, 1);            
        }

        /// <summary>
        /// Copy to Xna Matrix
        /// </summary>
        /// <param name="m"></param>
        /// <param name="xnaMatrix">Xna Matrix to fill</param>
        public static void ToXna(this DMatrix3 m, ref Matrix xnaMatrix)
        {
            xnaMatrix.M11 = m.M11;
            xnaMatrix.M12 = m.M12;
            xnaMatrix.M13 = m.M13;
            xnaMatrix.M14 = 0;

            xnaMatrix.M21 = m.M21;
            xnaMatrix.M22 = m.M22;
            xnaMatrix.M23 = m.M23;
            xnaMatrix.M24 = 0;

            xnaMatrix.M31 = m.M31;
            xnaMatrix.M32 = m.M32;
            xnaMatrix.M33 = m.M33;
            xnaMatrix.M34 = 0;

            xnaMatrix.M41 = m.M41;
            xnaMatrix.M42 = m.M42;
            xnaMatrix.M43 = m.M43;
            xnaMatrix.M44 = 0;
        }

        /// <summary>
        /// Convert to Ode DMatrix3
        /// </summary>
        /// <param name="m"></param>
        /// <returns>Ode DMatrix3</returns>
        public static DMatrix3 ToOde3(this Matrix m)
        {
            DMatrix3 mat = new DMatrix3();
            mat.M11 = m.M11;
            mat.M12 = m.M12;
            mat.M13 = m.M13;

            mat.M21 = m.M21;
            mat.M22 = m.M22;
            mat.M23 = m.M23;

            mat.M31 = m.M31;
            mat.M32 = m.M32;
            mat.M33 = m.M33;

            mat.M41 = m.M41;
            mat.M42 = m.M42;
            mat.M43 = m.M43;

            return mat;
        }

        /// <summary>
        /// Copy to Ode DMatrix3
        /// </summary>
        /// <param name="m"></param>
        /// <param name="odeMatrix">Ode DMatrix3 to fill</param>        
        public static void ToOde3(this Matrix m, ref DMatrix3 odeMatrix)
        {
            odeMatrix.M11 = m.M11;
            odeMatrix.M12 = m.M12;
            odeMatrix.M13 = m.M13;

            odeMatrix.M21 = m.M21;
            odeMatrix.M22 = m.M22;
            odeMatrix.M23 = m.M23;

            odeMatrix.M31 = m.M31;
            odeMatrix.M32 = m.M32;
            odeMatrix.M33 = m.M33;

            odeMatrix.M41 = m.M41;
            odeMatrix.M42 = m.M42;
            odeMatrix.M43 = m.M43;
        }
        #endregion

        #region Matrix4
        /// <summary>
        /// Convert to Xna Matrix
        /// </summary>
        /// <param name="m"></param>
        /// <returns>Xna Matrix</returns>
        public static Matrix ToXna(this DMatrix4 m)
        {
            return new Matrix(m.M11, m.M12, m.M13, m.M14,
                m.M21, m.M22, m.M23, m.M24,
                m.M31, m.M32, m.M33, m.M34,
                m.M41, m.M42, m.M43, m.M44);
        }

        /// <summary>
        /// Copy to Xna Matrix
        /// </summary>
        /// <param name="m"></param>
        /// <param name="xnaMatrix">Xna Matrix to fill</param>
        public static void ToXna(this DMatrix4 m, ref Matrix xnaMatrix)
        {
            xnaMatrix.M11 = m.M11;
            xnaMatrix.M12 = m.M12;
            xnaMatrix.M13 = m.M13;
            xnaMatrix.M14 = m.M14;

            xnaMatrix.M21 = m.M21;
            xnaMatrix.M22 = m.M22;
            xnaMatrix.M23 = m.M23;
            xnaMatrix.M24 = m.M24;

            xnaMatrix.M31 = m.M31;
            xnaMatrix.M32 = m.M32;
            xnaMatrix.M33 = m.M33;
            xnaMatrix.M34 = m.M34;

            xnaMatrix.M41 = m.M41;
            xnaMatrix.M42 = m.M42;
            xnaMatrix.M43 = m.M43;
            xnaMatrix.M44 = m.M44;
        }

        /// <summary>
        /// Convert to Ode DMatrix4
        /// </summary>
        /// <param name="m"></param>
        /// <returns>Ode DMatrix4</returns>
        public static DMatrix4 ToOde4(this Matrix m)
        {
            DMatrix4 mat = new DMatrix4();
            mat.M11 = m.M11;
            mat.M12 = m.M12;
            mat.M13 = m.M13;
            mat.M14 = m.M14;

            mat.M21 = m.M21;
            mat.M22 = m.M22;
            mat.M23 = m.M23;
            mat.M24 = m.M24;

            mat.M31 = m.M31;
            mat.M32 = m.M32;
            mat.M33 = m.M33;
            mat.M34 = m.M34;

            mat.M41 = m.M41;
            mat.M42 = m.M42;
            mat.M43 = m.M43;
            mat.M44 = m.M44;

            return mat;
        }

        /// <summary>
        /// Copy to Ode DMatrix4
        /// </summary>
        /// <param name="m"></param>
        /// <param name="odeMatrix">Ode DMatrix4 to fill</param>        
        public static void ToOde4(this Matrix m, ref DMatrix4 odeMatrix)
        {
            odeMatrix.M11 = m.M11;
            odeMatrix.M12 = m.M12;
            odeMatrix.M13 = m.M13;
            odeMatrix.M14 = m.M14;

            odeMatrix.M21 = m.M21;
            odeMatrix.M22 = m.M22;
            odeMatrix.M23 = m.M23;
            odeMatrix.M24 = m.M24;

            odeMatrix.M31 = m.M31;
            odeMatrix.M32 = m.M32;
            odeMatrix.M33 = m.M33;
            odeMatrix.M34 = m.M34;

            odeMatrix.M41 = m.M41;
            odeMatrix.M42 = m.M42;
            odeMatrix.M43 = m.M43;
            odeMatrix.M44 = m.M44;
        }
        #endregion

        #region Quaternion
        /// <summary>
        /// Convert to Xna Quaternion
        /// </summary>
        /// <param name="q"></param>
        /// <returns>Xna Quaternion</returns>
        public static Quaternion ToXna(this DQuaternion q)
        {
            return new Quaternion(q.X, q.Y, q.Z, q.W);
        }

        /// <summary>
        /// Copy to Xna Quaternion
        /// </summary>
        /// <param name="q"></param>        
        /// <param name="xnaQuaternion">Xna Quaternion to fill</param>
        public static void ToXna(this DQuaternion q, ref Quaternion xnaQuaternion)
        {
            xnaQuaternion.X = q.X;
            xnaQuaternion.Y = q.Y;
            xnaQuaternion.Z = q.Z;
            xnaQuaternion.W = q.W;
        }

        /// <summary>
        /// Convert to Ode DQuaternion
        /// </summary>
        /// <param name="q"></param>
        /// <returns>Ode DQuaternion</returns>
        public static DQuaternion ToOde(this Quaternion q)
        {
            return new DQuaternion(q.X, q.Y, q.Z, q.Z);
        }

        /// <summary>
        /// Copy to Ode DQuaternion
        /// </summary>
        /// <param name="q"></param>        
        /// <param name="odeQuaternion">Ode DQuaternion to fill</param>
        public static void ToOde(this Quaternion q, ref DQuaternion odeQuaternion)
        {
            odeQuaternion.X = q.X;
            odeQuaternion.Y = q.Y;
            odeQuaternion.Z = q.Z;
            odeQuaternion.W = q.W;
        }
        #endregion
    }
}
